![AWS KMSに利用者が作成した共通鍵をインポートする手順](https://devio2023-media.developers.io/wp-content/uploads/2015/08/kms.png)
AWS KMSに利用者が作成した共通鍵をインポートする手順
こんにちは、虎塚です。
先月のAWSアップデートで、利用者が作成した共通鍵をAWS KMSにインポートできるようになったので、概要と手順をご紹介します。
概要
これまでのAWS KMSでは、AWS側で生成された鍵(カスタマーデータキー)を元に作成したデータキーで、AWSリソースやユーザデータを暗号化/復号してきました。今回のアップデートで、カスタマーデータキーとして、ユーザがローカルで独自に作成した鍵も、カスタマーデータキーの1つとして利用できるようになりました。
カスタマーマスターキーは、Key Materialと呼ばれるデータと関係づけられることで有効化されます。これまで、Key Materialは、AWSが内部的に生成していました。これからは、Key MaterialとしてAWS外のデータを使うことができます。ユーザが作成したKey Materialが、「利用者が作成した共通鍵」です。
どんなケースで鍵をインポートすると便利か
鍵に特定の要件が求められるケース
鍵にシステム独自の基準が求められるような場合に、ユーザが制御できるようになりました。たとえば、鍵の生成に使用するシードのランダム性について、なんらかの基準を満たす必要があるとき、必要な設定に基づいてKey Materialを作成することで、基準をクリアできるでしょう。
これまでは、カスタマーマスターキーの生成をAWS KMSが内部的におこなっていたため、Key Materialの生成プロセスにユーザは関与できませんでした。
鍵の利用可能期間をあらかじめ設定したいケース
インポートした鍵から生成したカスタマーマスターキーには、ユーザが任意の有効期限を設定できます。また、カスタマーマスターキーと関連づけられたKey Materialを手動で削除することもできます。Key Materialを削除すると、カスタマーマスターキーは利用できない状態になります。もし再びカスタマーマスターキーが必要になったら、Key Materialを再アップロードすることで、復活させることができます。
これまでは、カスタマーデータキーを無効化するか、猶予期限を与えた上で削除することしかできませんでした。そして、カスタマーマスターキーを削除すると、二度と復活させることはできませんでした。
インポート機能の安全性
鍵の生成から破棄までがAWS側で完結するこれまでの機能と違い、本機能ではユーザが作成した鍵をインターネット経由でアップロードするので、セキュリティが気になる方もいらっしゃるかと思います。
鍵のインポートでは、AWSが発行する有効期限付きの公開鍵とインポートトークンを使います。インポートする共通鍵 (Key Material) を、公開鍵で暗号化してから、インポートトークンとともにアップロードすることで、AWS KMS側ではアップロードされた鍵の真正性を確認できます。言い換えると、途中の経路で改ざんされた鍵が有効化されることはありません。
また、カスタマーマスターキーにインポートされたKey Materialは、そのカスタマーマスターキーと永続的に関連づけられます。もし誰かがKey Materialを不正に入手して、自分のカスタマーマスターキーにインポートしても、その鍵では本来のカスタマーマスターキーで暗号化したデータを復号することはできません。
鍵のインポート手順
それでは、鍵のインポート手順を説明します。動作確認は次の環境でおこないました。
- Mac OS X 10.5.5 Yosemite
- AWS CLI 1.10.64 (botocore 1.4.54)
1. カスタマーマスターキーの作成
まず、カスタマーマスターキーをAWS KMSに作成します。この時、originに「EXTERNAL」を指定します。デフォルト値はAWS_KMSで、この場合は従来のインポートしない鍵が生成されます。
aws kms create-key --origin EXTERNAL --description imported_key
実行結果は、次のようになります。
{ "KeyMetadata": { "Origin": "EXTERNAL", "KeyId": "12345678-abcd-abcd-abcd-123456789012", "Description": "imported_key", "Enabled": false, "KeyUsage": "ENCRYPT_DECRYPT", "KeyState": "PendingImport", "CreationDate": 1473967382.465, "Arn": "arn:aws:kms:ap-northeast-1:123456789012:key/12345678-abcd-abcd-abcd-123456789012", "AWSAccountId": "123456789012" } }
Originが「EXTERNAL」になっていることと、KeyStateが「PendingImport」になっていることが重要です。生成されたカスタマーマスターキーのKey IDを控えておきましょう。
念のため、describeコマンドを使用して、生成コマンドの実行時と同じ情報が出力されることを確認します。
aws kms describe-key --key-id 12345678-abcd-abcd-abcd-123456789012
実行結果は、次のようになります。
{ "KeyMetadata": { "Origin": "EXTERNAL", "KeyId": "12345678-abcd-abcd-abcd-123456789012", "Description": "imported_key", "Enabled": false, "KeyUsage": "ENCRYPT_DECRYPT", "KeyState": "PendingImport", "CreationDate": 1473967382.465, "Arn": "arn:aws:kms:ap-northeast-1:123456789012:key/12345678-abcd-abcd-abcd-123456789012", "AWSAccountId": "123456789012" } }
2. 公開鍵とインポートトークンをダウンロード
ステップ1で生成したカスタマーマスターキーを指定して、ユーザが独自に生成する鍵をアップロードする時に必要な公開鍵とインポートトークンをダウンロードします。
ダウンロードする前に、アップロードする鍵の暗号化に利用する公開鍵暗号化方式で、どのpadding方式を使うかを選びます。ここで選んだ方式を、ダウンロード時にオプションとして指定する必要があるためです。次の3種類から選びます。
- RSAES_OAEP_SHA_256
- RSAES_OAEP_SHA_1
- RSAES_PKCS1_V1_5
aws kms get-parameters-for-import \ --key-id 12345678-abcd-abcd-abcd-123456789012 \ --wrapping-algorithm RSAES_PKCS1_V1_5 \ --wrapping-key-spec RSA_2048
今回は、RSAES_PKCS1_V1_5にします。wrapping-key-specオプションに指定できる値は、「RSA_2048」固定です。
実行結果は、次のようになります。
{ "ParametersValidTo": 1474058793.704, "PublicKey": "MIIBIjANBgkqhki...", "KeyId": "arn:aws:kms:ap-northeast-1:123456789012:key/12345678-abcd-abcd-abcd-123456789012", "ImportToken": "AQECAHhykjoG..." }
実行結果から得られた公開鍵 (PublicKey) とインポートトークン (ImportToken) をテキストファイルに保存します。ここでは、ファイル名をそれぞれPublicKey.b64、ImportToken.b64とします。
「ParametersValidTo」は、公開鍵とインポートトークンの有効期限を表わすタイムスタンプです。公開鍵とインポートトークンは、ダウンロードから24時間有効です。
date -r 1474058793 Sat Sep 17 05:46:33 JST 2016
3. 公開鍵とインポートトークンのデコード
公開鍵とインポートトークンをそれぞれbase64デコードして、新しいファイルに保存します。
$ openssl enc -d -a -A -in PublicKey.b64 -out PublicKey.bin $ openssl enc -d -a -A -in ImportToken.b64 -out ImportToken.bin
4. インポートする鍵の生成と暗号化
AWS KMSにインポートする鍵を作成します(これがKey Materialです)。ここでは、32bitのランダムビットを生成しました。
openssl rand -out PlaintextKeyMaterial.bin 32
生成した鍵を、ステップ3でデコードした公開鍵を使って暗号化します。
openssl rsautl -encrypt \ -in PlaintextKeyMaterial.bin \ -pkcs \ -inkey PublicKey.bin \ -keyform DER \ -pubin \ -out EncryptedKeyMaterial.bin
5. 暗号化した鍵のインポート
ステップ4で暗号化した鍵を、AWS KMSにインポートします。
今回は、インポートするKey Materialの期限を2016年12月10日に指定しました。暗号化した鍵 (Key Material) とインポートするトークンは、いずれもblobファイルとして「fileb://」で読み込みます。
aws kms import-key-material --key-id 12345678-abcd-abcd-abcd-123456789012 \ --encrypted-key-material fileb://EncryptedKeyMaterial.bin \ --import-token fileb://ImportToken.bin \ --expiration-model KEY_MATERIAL_EXPIRES \ --valid-to 2016-12-10T12:00:00-08:00
実行後、describeコマンドを使って鍵のメタデータを確認します。実行結果は、次のようになります。
aws kms describe-key --key-id 12345678-abcd-abcd-abcd-123456789012 { "KeyMetadata": { "Origin": "EXTERNAL", "KeyId": "12345678-abcd-abcd-abcd-123456789012", "Description": "imported_key", "ExpirationModel": "KEY_MATERIAL_EXPIRES", "ValidTo": 1481400000.0, "Enabled": true, "KeyUsage": "ENCRYPT_DECRYPT", "KeyState": "Enabled", "CreationDate": 1473967382.465, "Arn": "arn:aws:kms:ap-northeast-1:123456789012:key/12345678-abcd-abcd-abcd-123456789012", "AWSAccountId": "123456789012" } }
KeyStateが「Enabled」に変更されたことを確認します。
おわりに
ユーザが独自に作成した鍵をインポートできるようになったことで、AWS KMSを利用できる場面がさらに広がったと思います。
それでは、また。